﻿using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Practices.Unity;
using Oxite.Configuration;
using Oxite.Infrastructure;
using Oxite.Routing;
using Oxite.Validation;
using ECube.Web.CMS.Routing;
using ECube.Web.CMS.ModelBinders;
using ECube.Web.CMS.Models;
using ECube.Web.CMS.Services;
using ECube.Web.CMS.Repositories;
using ECube.Web.CMS.Repositories.SqlServer;
using ECube.Web.CMS.Validation;
using ECube.Web.CMS.Controllers;
using ECube.Web.CMS.Filters;
namespace ECube.Web.CMS
{
    public class ECubeCMSModule : IOxiteModule, IOxiteDataProvider
    {
        private readonly string[] controllerNamespaces;
        private readonly IUnityContainer container;

        public ECubeCMSModule(IUnityContainer container)
        {
            controllerNamespaces = new[] { "ECube.Web.CMS.Controllers" };
            this.container = container;
        }

        #region IOxiteModule Members

        public void Initialize(OxiteModuleConfigurationElement module)
        {
        }

        public void Unload()
        {
        }

        public void RegisterRoutes(RouteCollection routes)
        {
           
           routes.MapRoute(
                "AdminSiteNavigator", 
                "Admin/SiteNavigator/{action}/{key}",
                new { controller = "SiteNavigator", action = "Manage", key = UrlParameter.Optional, AllowAnonymous = true },//, DenyAnonymous=true }, 
                null, 
                controllerNamespaces
                );
           routes.MapRoute(
               "AdminWidget",
               "Admin/Widget/{action}/{id}",
               new { controller = "Widget", action = "Manage", id = UrlParameter.Optional },//, DenyAnonymous=true }, 
               null,
               controllerNamespaces
               );
           routes.MapRoute(
               "AdminPage",
               "Admin/Page/EditMeta/{id}",
               new { controller = "SitePage", action = "EditMeta", id = UrlParameter.Optional, AllowAnonymous = true },
               null,
               controllerNamespaces
               );
            //routes.MapRoute(
            //    "DeskIndex",
            //    "Admin/Desk",
            //    new { controller = "Desk", action = "Index"},
            //    null,
            //    controllerNamespaces
            //    );
            //routes.MapRoute(
            //    "DeskItem",
            //    "Admin/Desk/{name}",
            //    new { controller = "Desk", action = "Item",name="MyDesk" },
            //    null,
            //    controllerNamespaces
            //    );
            //routes.MapRoute
            //    ("SiteRoot",
            //    "{*pagePath}",
            //    new { controller = "SitePage", action = "Item" ,pagePath="" },
            //    new { pagePath = "(|default.aspx)" },
            //    controllerNamespaces
            //    );
        }

        public void RegisterCatchAllRoutes(RouteCollection routes)
        {
            routes.MapRoute(
                "SitePageAdd",
                "{*pagePath}",
                new { controller = "SitePage", action = "ItemAdd", pagePath = "" },
                new { pagePath = new IsSitePageMode(PageMode.Add) },
                controllerNamespaces
                );
            routes.MapRoute(
                "SitePageDesign",
                "{*pagePath}",
                new { controller = "SitePage", action = "ItemDesign", pagePath = "" },
                new { pagePath = new IsSitePageMode(PageMode.Design) },
                controllerNamespaces
                );
            routes.MapRoute(
                "SitePageEdit",
                "{*pagePath}",
                new { controller = "SitePage", action = "ItemEdit", pagePath = ""},
                new { pagePath = new IsSitePageMode(PageMode.Edit) },
                controllerNamespaces
                );

            routes.MapRoute(
                "SitePageAddContent",
                "{*pagePath}",
                new { controller = "SitePage", action = "ItemAddContent" },
                new { pagePath = new IsSitePageMode(PageMode.AddContent) },
                controllerNamespaces
                );

            routes.MapRoute(
                "SitePageEditContent",
                "{*pagePath}",
                new { controller = "SitePage", action = "ItemEditContent" },
                new { pagePath = new IsSitePageMode(PageMode.EditContent) },
                controllerNamespaces
                );

            routes.MapRoute(
                "SitePageRemove",
                "{*pagePath}",
                new { controller = "SitePage", action = "Remove" },
                new { pagePath = new IsSitePageMode(PageMode.Remove), httpMethod = new HttpMethodConstraint("POST") },
                controllerNamespaces
                );

            routes.MapRoute(
                "SitePage", 
                "{*pagePath}",
                new { controller = "SitePage", action = "Item", pagePath = "", AllowAnonymous =true}, 
                null, 
                controllerNamespaces
                );
               
        }

        public void RegisterFilters(IFilterRegistry filterRegistry)
        {
           
            //filterRegistry.Add(Enumerable.Empty<IFilterCriteria>(), typeof(ContentItemFilter));

            ControllerActionFilterCriteria urlAuthorizationCriteria = new ControllerActionFilterCriteria();
            urlAuthorizationCriteria.AddMethod<SitePageController>(p => p.Item(null));
            urlAuthorizationCriteria.AddMethod<SitePageController>(p => p.Design(null));
            urlAuthorizationCriteria.AddMethod<SitePageController>(p => p.Edit(null));
            urlAuthorizationCriteria.AddMethod<SitePageController>(p => p.SaveDesign(null,null));
            urlAuthorizationCriteria.AddMethod<SitePageController>(p => p.SaveEdit(null, null));
            filterRegistry.Add(new[] { urlAuthorizationCriteria }, typeof(UrlAuthorizationFilter));


           
            //ControllerActionFilterCriteria pageListActionCriteria = new ControllerActionFilterCriteria();
            //pageListActionCriteria.AddMethod<PageController>(p => p.Add(null));
            //pageListActionCriteria.AddMethod<PageController>(p => p.AddSave(null));
            //pageListActionCriteria.AddMethod<PageController>(p => p.Edit(null, null));
            //pageListActionCriteria.AddMethod<PageController>(p => p.SaveEdit(null, null));
            //filterRegistry.Add(new[] { pageListActionCriteria }, typeof(PageListActionFilter));

            //ControllerActionFilterCriteria adminActionsCriteria = new ControllerActionFilterCriteria();
            //adminActionsCriteria.AddMethod<PageController>(p => p.Add(null));
            //adminActionsCriteria.AddMethod<PageController>(p => p.AddSave(null));
            //adminActionsCriteria.AddMethod<PageController>(p => p.Edit(null, null));
            //adminActionsCriteria.AddMethod<PageController>(p => p.SaveEdit(null, null));
            //adminActionsCriteria.AddMethod<PageController>(p => p.Remove(null, null));
            //filterRegistry.Add(new[] { adminActionsCriteria }, typeof(AuthorizationFilter));
        }

        public void RegisterModelBinders(ModelBinderDictionary modelBinders)
        {
            modelBinders[typeof(PageProfile)] = new PageProfileModelBinder();
            modelBinders[typeof(Page)] = container.Resolve<PageModelBinder>();
            modelBinders[typeof(MvcSiteMapNode)] = new MvcSiteMapNodeModelBinder();
            //modelBinders[typeof(ContentItemInput)] = new ContentItemInputModelBinder();
            //modelBinders[typeof(ContentItemsInput)] = new ContentItemsInputModelBinder();
        }

        public void RegisterWithContainer()
        {
            container
                .RegisterType<IPageService, PageService>()
                .RegisterType<IWidgetService,WidgetService>()
                .RegisterType<IValidator<PageInput>, PageInputValidator>();
               // .RegisterType<IValidator<MvcSiteMapNodeInput>, MvcSiteMapNodeInputValidator>();
            //    .RegisterType<IContentItemService, ContentItemService>();
        }

        #endregion

        #region IOxiteDataProvider Members

        public void ConfigureProvider(OxiteConfigurationSection config, OxiteDataProviderConfigurationElement dataProviderConfig, IUnityContainer container)
        {
            string connStr = !string.IsNullOrEmpty(dataProviderConfig.ConnectionString) ? dataProviderConfig.ConnectionString : config.Providers.DefaultConnectionString;
            if (dataProviderConfig.Category == "LinqToSql")
                container
                    .RegisterType<ECubeWebCMSDataContext>(new InjectionConstructor(new ResolvedParameter<string>(connStr)))
                    .RegisterType<IPageRepository, SqlServerPageRepository>()
                    .RegisterType<IContentItemRepository, SqlServerContentItemRepository>()
                    .RegisterType<IWidgetRepository,SqlServerWidgetRepository>();
        }

        #endregion
    }
}
